package com.report.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.zhxu.bs.util.MapBuilder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.zhxu.bs.BeanSearcher;
import cn.zhxu.bs.SearchResult;
import cn.zhxu.bs.operator.Contain;
import cn.zhxu.bs.operator.Equal;
import cn.zhxu.bs.util.MapUtils;
import com.report.constants.TagConstants;
import com.report.dto.request.OrderReq;
import com.report.dto.response.OrderRes;
import com.report.entity.Member;
import com.report.entity.Order;
import com.report.entity.Rule;
import com.report.mapper.OrderMapper;
import com.report.service.IMemberRuleService;
import com.report.service.IMemberService;
import com.report.service.IOrderService;
import com.report.utils.LocalDateUtils;
import com.zmh.framework.constants.Constants;
import com.zmh.framework.redis.RedisCache;
import com.zmh.framework.sys.dto.request.common.PageResponseDTO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author summer
 * @since 2024/06/27 19:48:57
 */
@Service
@Transactional(rollbackFor = Exception.class)
@AllArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final BeanSearcher beanSearcher;

    @Override
    public Page<OrderRes> lists(OrderReq orderReq) {
        Page<OrderRes> page=new Page<>(orderReq.getPageNum(),orderReq.getPageSize());
        Map<String, Object> build = MapUtils.builder().page(orderReq.getPageNum() - 1, orderReq.getPageSize())
                .field(OrderRes::getName, orderReq.getName()).op(Contain.class)
                .field(OrderRes::getPhone, orderReq.getPhone()).op(Contain.class)
                .field(OrderRes::getOrderNum, orderReq.getOrderNum()).op(Contain.class)
                .field(OrderRes::getPayMethod, orderReq.getPayMethod()).op(Equal.class).build();

        SearchResult<OrderRes> search = beanSearcher.search(OrderRes.class, build);
        page.setTotal(search.getTotalCount().longValue());
        page.setRecords(search.getDataList());
        return page;
    }


    @Override
    public Page<OrderRes> memberOrderList(PageResponseDTO pageResponseDTO) {
        Page<OrderRes> page=new Page<>(pageResponseDTO.getPageNum(),pageResponseDTO.getPageSize());
        MapBuilder op = MapUtils.builder().page(pageResponseDTO.getPageNum() - 1, pageResponseDTO.getPageSize())
                .field(OrderRes::getMemberId, StpUtil.getLoginId()).op(Equal.class)
                .field(OrderRes::getOrderStatus, Constants.TWO).op(Equal.class);
        SearchResult<OrderRes> search = beanSearcher.search(OrderRes.class, op.build());
        page.setTotal(search.getTotalCount().longValue());
        page.setRecords(search.getDataList());
        return page;
    }

    private final IMemberService memberService;

    private final IMemberRuleService memberRuleService;

    private final RedisCache redisCache;

    @Override
    public OrderRes updateOrderState(String orderNo) {
        //更新订单
        LambdaQueryWrapper<Order> eq = Wrappers.lambdaQuery(Order.class).eq(Order::getOrderNum, orderNo);
        Order order = this.getOne(eq);
        order.setOrderStatus(Constants.TWO);
        this.updateById(order);
        Integer memberRule = order.getMemberRule();
        Integer memberId = order.getMemberId();
        Member member = memberService.getById(memberId);
        member.setRuleId(memberRule);
        Rule rule = memberRuleService.getById(memberRule);
        if(rule.getVip()>Constants.ZERO){
            LocalDate effectiveTime = member.getEffectiveTime();
            LocalDate localDate = LocalDateUtils.plusDays(rule.getVip());
            int days= rule.getVip()+Long.bitCount(LocalDateUtils.day(effectiveTime));
            member.setEffectiveTime(LocalDateUtils.add(effectiveTime,localDate));
            member.setMemberState(1);
            memberService.updateById(member);
            redisCache.set(TagConstants.KEY_EXPIRATION+memberId, String.valueOf(memberId),days, TimeUnit.DAYS);
        }

        return Convert.convert(OrderRes.class, order);
    }


}
